#pragma once
#include <functional>
#include <iostream>
#include <iterator>
#include <list>
#include <string>
#include <vector>
using Line = std::vector<char>;
class Text_iterator : public std::iterator<std::forward_iterator_tag, char>
{
public:
    Text_iterator(std::list<Line>::iterator ll, Line::iterator pp) : ln(ll), pos(pp) {}
    std::list<Line>::iterator line() const { return ln; }
    Line::iterator position() const { return pos; }
    reference operator*() const { return *pos; }
    Text_iterator &operator++();
    bool operator==(const Text_iterator &other) const { return ln == other.ln && pos == other.pos; }
    bool operator!=(const Text_iterator &other) const { return !(*this == other); }

private:
    std::list<Line>::iterator ln;
    Line::iterator pos;
};

struct Document
{
    std::list<Line> line;
    using iterator = Text_iterator;
    Document() { line.emplace_back(); }
    iterator begin();
    iterator end();
    iterator insert(iterator p, iterator first, iterator last);
    iterator insert(iterator p, const std::string &s);
    int replace_all(const std::string &target, const std::string &replacement);
    iterator erase(iterator first, iterator last);
};
std::istream &operator>>(std::istream &is, Document &d);
std::ostream &operator<<(std::ostream &os, Document &d);
Document create_document(const std::string &text);
Text_iterator find_txt(Text_iterator first, Text_iterator last, const std::string &s);
void erase_line(Document &d, int n);
int character_count(Text_iterator frist, Text_iterator last);
int word_count(Text_iterator first, Text_iterator last, std::function<bool(char)> is_whitespace);
int word_count(Text_iterator first, Text_iterator last);
int word_count(Text_iterator first, Text_iterator last, const std::string &whitespace);